# --coding:utf-8--

# Copyright 2021 xpstem.com
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import unittest
from lelink.ev3operation import *
from lelink.ev3command import *
from lelink.conn.wificonnection import *
from lelink.ev3type import *


class EV3CommOpTest(unittest.TestCase):

    def setUp(self) -> None:
        self._conn = WifiConnection()
        self._conn.connect()

    def tearDown(self) -> None:
        self._conn.disconnect()

    def test_set_brickname(self):
        op = EV3CommOpFactory.com_set_brickname("EV3")
        cmd = EV3DirectCommand({op}, CommandType.DIRECT_COMMAND_REPLY)

        self._conn.send(cmd)
        self.assertEqual(ReplyType.DIRECT_REPLY_OK, cmd.reply_type)

    def test_get_brickname(self):
        name = ReturnParam(0, 16, DataS(""))
        op = EV3CommOpFactory.com_get_brickname(16, name)
        cmd = EV3DirectCommand({op}, CommandType.DIRECT_COMMAND_REPLY)

        self._conn.send(cmd)
        self.assertEqual(ReplyType.DIRECT_REPLY_OK, cmd.reply_type)
        self.assertEqual("EV3", name.value.value)


class EV3GeneralOpTest(unittest.TestCase):

    def setUp(self) -> None:
        self._conn = WifiConnection()
        self._conn.connect()

    def tearDown(self) -> None:
        self._conn.disconnect()

    def test_nop(self):
        op = EV3GeneralOpFactory.nop()
        cmd = EV3DirectCommand({op})

        self._conn.send(cmd)
        self.assertEqual(ReplyType.DIRECT_REPLY_OK, cmd.reply_type)


class EV3InputOpTest(unittest.TestCase):

    def setUp(self) -> None:
        self._conn = WifiConnection()
        self._conn.connect()

    def tearDown(self) -> None:
        self._conn.disconnect()

    # Port 1
    def test_device_gettypemode(self):

        type_ = ReturnParam(0, Data8(0))
        mode = ReturnParam(1, Data8(0))

        op = EV3InputOpFactory.OpInputDevice.get_typemode(Layer.L0, InputPort.A, type_, mode)
        cmd = EV3DirectCommand({op}, CommandType.DIRECT_COMMAND_REPLY)

        self._conn.send(cmd)

        self.assertEqual(ReplyType.DIRECT_REPLY_OK, cmd.reply_type)


class EV3OutputOpTest(unittest.TestCase):

    def setUp(self) -> None:
        self._conn = WifiConnection()
        self._conn.connect()

    def tearDown(self) -> None:
        self._conn.disconnect()

    def test_power_and_start(self):
        power_op = EV3OutputOpFactory.output_power(Layer.L0, {OutputPort.A}, 50)
        start_op = EV3OutputOpFactory.output_start(Layer.L0, {OutputPort.A})

        cmd = EV3DirectCommand({power_op, start_op}, CommandType.DIRECT_COMMAND_REPLY)
        self._conn.send(cmd)

        self.assertEqual(ReplyType.DIRECT_REPLY_OK, cmd.reply_type)

    def test_stop(self):
        stop_op = EV3OutputOpFactory.output_stop(Layer.L0, {OutputPort.A}, Brake.FLOAT)

        cmd = EV3DirectCommand({stop_op}, CommandType.DIRECT_COMMAND_REPLY)

        self._conn.send(cmd)

        self.assertEqual(ReplyType.DIRECT_REPLY_OK, cmd.reply_type)


if __name__ == '__main__':
    unittest.main()
